/*
 * schedule.c
 *
 *  Created on: Apr 19, 2015
 *      Author: mxw
 */
#include <schedule.h>
#include <commlib.h>
#include <LedDrv.h>
#include <UartDrv.h>

/*
         0x34000000 +--------------------------------+ 64M
        size:512k   |         task[0] stack          |
         0x33f80000 +--------------------------------+ 63M
        size:512k   |         task[1] stack          |
         0x33f00000 +--------------------------------+ 63M
                    |                                |
                    |         ...                    |
                    |                                |
         0x33080000 +--------------------------------+ 48M
        size:512k   |         task[31] stack         |
         0x33000000 +--------------------------------+ 48M
        size:512k   |         irq stack              |
         0x32f80000 +--------------------------------+ 47M
                    |                                |
                    |                                |
         size:31M   |         heap                   |
                    |                                |
                    |                                |
         0x31000000 +--------------------------------+ 16M
          size:16M  |         code + data            |
         0x30000000 +--------------------------------+ 0
                    |         invalid                |
             0x1000 +--------------------------------+
            size:4k |         guide code             |
               0x0  +--------------------------------+




 */

extern int main();
extern void set_task_sp(unsigned long);

task_manager g_tsk_mgr;
task_regs* g_pcurrent_regs = 0;
unsigned long sche_tmp_pc = 0;
unsigned long sche_tmp_r0 = 0;

extern void restore_run(void* pr);

int task_test2() {
    unsigned long i = 0;

    while(1){
        uart_print("A");

        set_led(LED_1, LED_ON);
        set_led(LED_2, LED_ON);
        set_led(LED_3, LED_ON);
        set_led(LED_4, LED_ON);
        while(i < 0xFFFF) {
            i++;
        }
        i = 0;
    }
}

int task_test3() {
    unsigned long i = 0;

    while(1){
        uart_print("C");
        set_led(LED_3, LED_ON);
        set_led(LED_4, LED_ON);
        while(i < 0xFFFF) {
            i++;
        }
        i = 0;
    }
}

void init_task() {
    int i = 0;

    my_memset(&g_tsk_mgr, 0, sizeof(g_tsk_mgr));
    for(i = 1; i < MAX_TASK_COUNT; ++i) {
        g_tsk_mgr.arr[i].is_first_run = 1;
        g_tsk_mgr.arr[i].priority = 0xFF;//lowest
        g_tsk_mgr.arr[i].st = ST_TASK_INVALID;
    }

    g_tsk_mgr.arr[0].entry = main;
    g_tsk_mgr.arr[0].is_first_run = 0;
    g_tsk_mgr.arr[0].priority = 10;
    //g_tsk_mgr.arr[0].r do not setting now.
    g_tsk_mgr.arr[0].st = ST_TASK_RUNNING;
    g_pcurrent_regs = &g_tsk_mgr.arr[0].r;


    g_tsk_mgr.arr[1].entry = task_test2;
    g_tsk_mgr.arr[1].is_first_run = 1;
    g_tsk_mgr.arr[1].priority = 255;//most low
    g_tsk_mgr.arr[1].st = ST_TASK_RUNNING;

    g_tsk_mgr.arr[2].entry = task_test3;
    g_tsk_mgr.arr[2].is_first_run = 1;
    g_tsk_mgr.arr[2].priority = 255;//most low
    g_tsk_mgr.arr[2].st = ST_TASK_RUNNING;



}

unsigned short get_next_task_id() {
    unsigned short ret = IVALID_TASK_ID;
    static unsigned long __tmp_test = 0;

//    for(i = 0; i < MAX_TASK_COUNT; ++i) {
//        if (ST_TASK_RUNNING == g_tsk_mgr.arr[i].st) {
//            tmp = (g_tsk_mgr.arr[i].hunger_value >> 2);// => /2   255/125
//            tmp += g_tsk_mgr.arr[i].priority;
//            if (tmp > v) {
//                ret = i;
//            }
//        }
//    }
    __tmp_test++;
    if (__tmp_test >= 10) {
        __tmp_test = 0;
    }

    if (__tmp_test < 8) {
        ret = 0;
    } else if (__tmp_test < 10) {
        ret = 1;
    }
    if (__tmp_test == 5) {
        ret = 2;
    }


    return ret;
}


void schedule() {
    unsigned short idx = 0;

    idx = get_next_task_id();
    if (IVALID_TASK_ID != idx) {
        g_pcurrent_regs = &g_tsk_mgr.arr[idx].r;
        if (1 == g_tsk_mgr.arr[idx].is_first_run) {
            g_tsk_mgr.arr[idx].is_first_run = 0;
            set_task_sp(0x34000000 - idx * 512 * 1024);
            g_tsk_mgr.arr[idx].entry();
        } else {
            restore_run(&g_tsk_mgr.arr[idx].r);
        }
    }

    while(1){}
}




























